#ifndef PCG_NOISE_H
#define PCG_NOISE_H

/*!
@header Noise
blah blah blah
@copyright James Callender
@updated 2007-02-09
*/

/*!
1D noise primitive functor definition.
*/
typedef float (*pcg_noise1_fn_t)(float);
/*!
2D noise primitive functor definition.
*/
typedef float (*pcg_noise2_fn_t)(float, float);
/*!
3D noise primitive functor definition.
*/
typedef float (*pcg_noise3_fn_t)(float, float, float);

// noise primitives

/*!
@functiongroup Noise Primitives
*/

/*!
1D coherent noise basis. Uses the value-noise algorithm. Returns the value at x.
*/
float pcg_vnoise1(float x);
/*!
2D coherent noise basis. Uses the value-noise algorithm. Returns the value at the point (x, y).
*/
float pcg_vnoise2(float x, float y);
/*!
3D coherent noise basis. Uses the value-noise algorithm. Returns the value at the point (x, y, z).
*/
float pcg_vnoise3(float x, float y, float z);

/*!
1D coherent noise basis. Uses the gradient-noise algorithm. Returns the value at x.
*/
float pcg_gnoise1(float x);
/*!
2D coherent noise basis. Uses the gradient-noise algorithm. Returns the value at the point (x, y).
*/
float pcg_gnoise2(float x, float y);
/*!
2D coherent noise basis. Uses the gradient-noise algorithm. Returns the value at the point (x, y, z).
*/
float pcg_gnoise3(float x, float y, float z);

// noise utilities

/*!
@functiongroup Noise Functions
*/

/*!
Fractal Brownian Motion
@return Returns the noise value at the specified point
@param prim Noise primitive callback to be used for noise
@param H Fractal dimension
@param lacunarity blah blah
@param octaves Number of octaves
*/
float pcg_fBm1(float x, pcg_noise1_fn_t prim, float H, float lacunarity, float octaves);
/*!
See @link pcg_fBm1 pcg_fBm1 @/link
*/
float pcg_fBm2(float x, float y, pcg_noise2_fn_t prim, float H, float lacunarity, float octaves);
/*!
See @link pcg_fBm1 pcg_fBm1 @/link
*/
float pcg_fBm3(float x, float y, float z, pcg_noise3_fn_t prim, float H, float lacunarity, float octaves);
/*!
Multifractal Noise
@return Returns the noise value at the specified point
@param prim Noise primitive callback to be used for noise
@param H Fractal dimension
@param lacunarity blah blah
@param octaves Number of octaves
@param offset Offset value
*/
float pcg_multifractal1(float x, pcg_noise1_fn_t prim, float H, float lacunarity, int octaves, float offset);
/*!
See @link pcg_multifractal1 pcg_multifractal1 @/link
*/
float pcg_multifractal2(float x, float y, pcg_noise2_fn_t prim, float H, float lacunarity, int octaves, float offset);
/*!
See @link pcg_multifractal1 pcg_multifractal1 @/link
*/
float pcg_multifractal3(float x, float y, float z, pcg_noise3_fn_t prim, float H, float lacunarity, int octaves, float offset);

float pcg_hetero1(float x, pcg_noise1_fn_t prim, float H, float lacunarity, float octaves, float offset);
float pcg_hetero2(float x, float y, pcg_noise2_fn_t prim, float H, float lacunarity, float octaves, float offset);
float pcg_hetero3(float x, float y, float z, pcg_noise3_fn_t prim, float H, float lacunarity, float octaves, float offset);

/*!
Distortion Noise
@return Returns the noise value at the specified point
@param prim Noise primitive callback to be used for noise
@param dist Noise primitive callback used to generate displacement vectors
@param scale Distortion multiplier
*/
float pcg_distnoise1(float x, pcg_noise1_fn_t prim, pcg_noise1_fn_t dist, float scale);
/*!
See @link pcg_distnoise1 pcg_distnoise1 @/link
*/
float pcg_distnoise2(float x, float y, pcg_noise2_fn_t prim, pcg_noise2_fn_t dist, float scale);
/*!
See @link pcg_distnoise1 pcg_distnoise1 @/link
*/
float pcg_distnoise3(float x, float y, float z, pcg_noise3_fn_t prim, pcg_noise3_fn_t dist, float scale);

/*!
Initializes tables used by the pcg_vnoise and pcg_gnoise primitives
*/
void pcg_snoise(int seed);

#endif // PCG_NOISE_H